#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define all(s) s.begin(), s.end()
const int MOD = 998244353;

struct ver {
	int r, win, v, mn;
	// r = 0 => ALL determined. In this case, value is determined.
	// r = 1 => ALL undetermined. In this case, value is unlimited.
	// r = 2 => L is determined, R is undetermined. 
	//          In this case, we will use =v or >=mn.
};

void solve() {
	int n, m; cin >> n >> m;
	vector<int> A(n + 1), a(n + 1), c(m + 1);
	for (int i = 1; i <= n; i++) cin >> A[i];
	for (int i = 1; i <= m; i++) cin >> c[i];
	int l = 0, M = 1;
	while (M <= n) {
		l++;
		M <<= 1;
	}
	vector<vector<int>> d(l + 1, vector<int>());
	for (int i = 1; i <= l; i++) {
		string s; cin >> s;
		int o = s.size();
		d[i].emplace_back(0);
		for (int j = 0; j < o; j++) d[i].emplace_back(s[j] - '0');
	}
	int T; cin >> T;
	vector<int> ans(n + 1);
	vector<int> lose(2 * M + 2);
	while (T--) {
		vector<ver> u(2 * M, (ver){1, -1, -1, -1});
		vector<int> X(4);
		vector<int> candidate;
		for (int i = 0; i < 4; i++) cin >> X[i];
		for (int i = 1; i <= n; i++) a[i] = A[i] ^ X[i % 4], ans[i] = 0;
		for (int i = 1; i <= 2 * M + 1; i++) lose[i] = 0;
		ll sum = 0;
		int lstP = 0;
		for (int i = 1; i <= n; i++) {
			// cout << "updating " << i << endl;
			int P = 1;
			while (P < i) P <<= 1;
			if (P != lstP) {
				for (int j = lstP + 1; j <= P; j++) {
					if (!lose[M + j - 1]) {
						sum += j;
						// cout << "+ " << j << endl;
					}
				}
			}
			lstP = P;
			auto L = [&](auto self, int u) -> void {
				if (lose[u]) return;
				lose[u] = 1;
				if (u >= M) {
					// u - M + 1 lose;
					// cout << u - M + 1 << " lose!" << endl;
					// cout << "- " << u - M + 1 << endl;
					if (u - M + 1 <= P) sum -= u - M + 1;
					return;
				}
				int lc = 2 * u, rc = 2 * u + 1;
				if (!lose[lc]) self(self, lc);
				if (!lose[rc]) self(self, rc);
			};
			int cur = M + i - 1;
			u[cur] = {0, i, a[i], -1};
			int now = 0;
			while (cur != 1) {
				cur /= 2; now++;
				int lc = 2 * cur, rc = 2 * cur + 1;
				// upd cur.
				int g = (cur - (M >> now)) + 1;
				int q = d[now][g];
				if (q != 0) swap(lc, rc);
				if (u[lc].r == 0) {
					if (u[lc].v >= now) {
						// TBD: rc LOSE!
						L(L, rc);
						u[cur] = u[lc];
					} else {
						// TBD: lc LOSE!
						L(L, lc);
						u[cur] = u[rc];
					}
				} else if (u[lc].r == 1) {
					u[cur] = {2, -1, u[rc].v, now};
				} else {
					u[cur] = {2, -1, u[lc].v, u[lc].mn};
					if (u[lc].v >= now) {
						// TBD: rc LOSE!
						// cout << "this3" << endl;
						L(L, rc);
					} else {
						if (u[rc].r == 0) {
							u[cur].v = u[rc].v;
						} else {
							u[cur].r = 1;
						}
					}
				}
			}
			if (!lose[M + i - 1]) candidate.push_back(i);
			vector<int> nw;
			for (auto x : candidate) {
				if (lose[M + x - 1]) continue;
				int cur = M + x - 1;
				bool flag = 0;
				int now = 0;
				while (cur != 1) {
					now++;
					int lst = cur;
					cur /= 2;
					int g = (cur - (M >> now)) + 1;
					if (d[now][g] == (lst == 2 * cur + 1)) {
						if (a[x] < now) {
							flag = 1;
							break;
						}
					}
				}
				if (!flag) {
					nw.push_back(x);
				} else {
					sum -= x;
					// cout << x << " c lose!" << endl;
				}
			}
			candidate.swap(nw);
			// cout << i << ' ' << sum << '\n';
			ans[i] = sum;
		}
		ll F = 0;
		for (int i = 1; i <= m; i++) F ^= 1ll * i * ans[c[i]];
		cout << F << '\n';
		// cerr << "-----" << endl;
	}
}

int main() {
	auto start = chrono::steady_clock::now();
	freopen("arena.in", "r", stdin);
	freopen("arena.out", "w", stdout);
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	solve();
	auto end = chrono::steady_clock::now();
	cerr << "time: " << chrono::duration<double, milli>(end - start).count() << "ms" << endl;
}